﻿<#
.SYNOPSIS 
    Retrieves the PeopleSoft Application Server features.
.DESCRIPTION 
    Use this command to retrieve the PeopleSoft Application Server advanced configuration parameters for a specific domain.
    This command identifies servers that are maked to boot when the Application Server boots (PUBSUB, JOLT, etc)
.NOTES 
    File Name  : Get-PsftFeature.ps1 
    Author     : Scott Kearney - scott@kearney.tk 
    Requires   : PowerShell V3 
.EXAMPLE 
    Get-PsftFeature -PS_HOME C:\psoft\PS_HOME -PS_CFG_HOME C:\psoft\PS_CFG_HOME -ServerType AppServer -Domain DOMAIN1 -Name JOLT
    Retrieves the value of the JOLT configuration option.
.PARAMETER PS_HOME
    The full path to the PS_HOME directory for this domain.
.PARAMETER PS_CFG_HOME
    The full path to the PS_CFG_HOME directory for this domain.
.PARAMETER ServerType
    The type of server on which to perform the action.
.PARAMETER Domain
    The name of the domain on which to perform the action.
.PARAMETER Name
    If specified, limits the scope to only options with this name in the configuration file.
#> 
function Get-PsftFeature
{
    [CmdletBinding(SupportsShouldProcess=$True,ConfirmImpact='Low')]
    [OutputType([boolean])]
    Param
    (
        # The full path to the PS_HOME directory for this domain.
        # See http://docs.oracle.com/cd/E41633_01/pt853pbh1/eng/pt/tsvt/concept_UnderstandingPS_HOMEandPS_CFG_HOME-eb7ece.html
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The full path to the PS_HOME directory for this domain.",
                   Position=0)]
        [ValidateScript({Validate_PS_HOME $_})]
        [String]
        $PS_HOME,

        # The full path to the PS_CFG_HOME directory for this domain.
        # See http://docs.oracle.com/cd/E41633_01/pt853pbh1/eng/pt/tsvt/concept_UnderstandingPS_HOMEandPS_CFG_HOME-eb7ece.html
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The full path to the PS_CFG_HOME directory for this domain.",
                   Position=1)]
        [ValidateScript({Validate_PS_CFG_HOME $_})]
        [String]
        $PS_CFG_HOME,

        # The type of server on which to perform the action.
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The type of server on which to perform the action.",
                   Position=2)]
        [ValidateSet("AppServer","PrcsScheduler")]
        $ServerType,

        # The name of the domain on which to perform the action.
        # Should be a directory under the PS_CFG_HOME
        [Parameter(Mandatory=$true,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "The name of the domain on which to perform the action.",
                   Position=3)]
        [ValidateScript({Validate_Domain $PS_CFG_HOME $ServerType $_})]
        [String]
        $Domain,
        
        # If specified, limits the scope to only options with this name in the configuration file.
        # Should be an option name from psappsrv.ubx
        # E.g. JOLT
        [Parameter(Mandatory=$false,
                   ValueFromPipelineByPropertyName=$true,
                   HelpMessage = "An option name from psappsrv.ubx. E.g. ""JOLT""",
                   Position=3)]
        [String]
        $Name
    )

    Begin
    {
    }
    Process
    {
        # Set up variables
        $featureTable = @{}; 
        
        # Parse the values from the ps*.ubx file
        switch ($ServerType)
        {
            'PrcsScheduler' {$UBXfile = "$PS_CFG_HOME\appserv\prcs\$Domain\psprcsrv.ubx"}
                'AppServer' {$UBXfile =  "$PS_CFG_HOME\appserv\$Domain\psappsrv.ubx"}
        }

        # Search file lines in the UBX file which follow this pattern: {SomeText} Some more text? [A character (should be y or n)]
        Write-Verbose "Parsing: $UBXfile"
        $featureLines  = Select-String -Path $UBXfile -Pattern "^{[\w]*}[^\[]*\[[\w]\]" | select -exp Line 

        # Using the same regex search, pull out the relevant bits from those lines, and write them as a string, separated by a colon
        $featureValues = $featureLines -replace "^{([\w]*)}[^\[]*\[([\w])\].*","`$1:`$2"

        # For each line, split up the string by the colon
        # Create a hash table and assign the value in front of the colon to the name
        # Parse the value after the colon into a boolean value, based on y/n value
        Write-Verbose "Retrieved: $featureValues"
        $featureValues | ForEach-Object{ 
                            $featureTable += @{
                                $(($_ -split ':')[0]) = $(
                                    switch(($_ -split ':')[1]){
                                        'y' {$true}
                                        'n' {$false}
                                        Default {$false}
                                    }
                                )
                            }
                        }

        # Convert the hash table to a PowerShell Object (Converting to and from JSON does this nicely)
        # Why do we want an object instead of a hash table? I'm not sure. Maybe stick with the hash table in another revision?
        $featureObject = $featureTable | ConvertTo-Json | ConvertFrom-Json
        
        # Return the appropriate values, based on the search parameters
        if(($featureObject.$Name -ne "") -and ($Name -ne ""))
        {
            # The name was requested and exists in the list

            $return = $featureObject | Select @{
                Name="$Name";
                Expression={$_.$Name}
            }

            return $return

        } 
        elseif (($featureObject.$Name -eq "") -and ($Name -ne "")) 
        {
            # A name was requested which does not exist

            throw "$Name is not a valid configuration option."
        } 
        else 
        {
            # A name was not specified, so return the whole object with all values
            return $featureObject
        }

    }
    End
    {
    }
}